package whu.cachhe.makeorder.ui;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import whu.cachhe.makeorder.R;
import whu.cachhe.makeorder.domain.News;
import whu.cachhe.makeorder.domain.User;
import whu.cachhe.makeorder.net.HttpRequest;
import whu.cachhe.makeorder.net.URLConstant;
import whu.cachhe.makeorder.util.DateTimeUtil;
import whu.cachhe.makeorder.util.Logger;
import whu.cachhe.makeorder.view.ImageTextView;
import whu.cachhe.makeorder.view.SimpleDateTimePicker;
import whu.cachhe.makeorder.view.WrapContentListView;

/**
 * -- 877c212e-3295-11e8-a262-00163e104758 一般用户
 -- 912a6a6e-3295-11e8-a262-00163e104758 残疾人A
 -- 980f5538-3295-11e8-a262-00163e104758 残疾人B
 */

public class MainActivity extends CheckPermissionsActivity {
    protected static User user;

    private ImageView imgBg;
    private ImageTextView itvReservations, itvScan, itvReport, itvPolicy, itvMyReservations, itvOther;
    private ImageTextView itvNewsMore;
    private WrapContentListView listView;

    private List<News> newsList;
    private NewsAdapter newsAdapter;

    private SimpleDateTimePicker timePicker;

    private static final int REQUEST_SCAN_CODE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        user = getIntent().getParcelableExtra("user");
        if (user == null)
            finish(); // 直接返回

        setContentView(R.layout.activity_main);

        init();
    }

    private void init() {
        itvReservations = findViewById(R.id.itv_make_reservations);
        itvScan = findViewById(R.id.itv_scan);
        itvReport = findViewById(R.id.itv_report);
        itvPolicy = findViewById(R.id.itv_policy);
        itvMyReservations = findViewById(R.id.itv_my_reservations);
        itvOther = findViewById(R.id.itv_other);

        itvNewsMore = findViewById(R.id.itv_news_more);
        listView = findViewById(R.id.list_view);

        imgBg = findViewById(R.id.img_bg);
        Glide.with(this).load(R.mipmap.reservations_bg).into(imgBg);

        initListener();

        newsList = new ArrayList<>();
        newsAdapter = new NewsAdapter(MainActivity.this, newsList);
        listView.setAdapter(newsAdapter);
        getRecentNews();
    }

    private boolean isDisabledPeople(User user){
        return user.getUserType() == 0;
    }

    private void initListener(){
        View.OnClickListener ocl = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (v.getId()){
                    case R.id.itv_make_reservations:
                        if (isDisabledPeople(user))
                            startActivity(new Intent(MainActivity.this, ReservationsActivity.class));
                        else
                            Toast.makeText(MainActivity.this, "非障碍人士不能预约", Toast.LENGTH_LONG).show();
                        break;
                    case R.id.itv_scan:
                        IntentIntegrator integrator = new IntentIntegrator(MainActivity.this);
                        integrator.setCaptureActivity(ScanActivity.class);
                        integrator.setRequestCode(REQUEST_SCAN_CODE);
                        integrator.setPrompt("");
                        integrator.setBeepEnabled(false);
                        integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE);
                        integrator.setOrientationLocked(true);
                        integrator.initiateScan();
                        break;
                    case R.id.itv_report:
                        Intent intent = new Intent(MainActivity.this, ReportScanActivity.class);
                        startActivity(intent);
                        break;
                    case R.id.itv_my_reservations:
                        startActivity(new Intent(MainActivity.this, MyReservationsActivity.class));
                        break;
                }
            }
        };

        itvReservations.setOnClickListener(ocl);
        itvScan.setOnClickListener(ocl);
        itvReport.setOnClickListener(ocl);
        itvMyReservations.setOnClickListener(ocl);
    }

    private void getRecentNews(){
        JSONObject fparam = new JSONObject();
        try {
            fparam.put("uid", user.getReserveSysId());
        } catch (JSONException e) {
            e.printStackTrace();
            return;
        }

        HttpRequest.post(URLConstant.HOST, "getRecentNews", fparam, new HttpRequest.HttpRequestCallback() {
            @Override
            public void onSuccess(JSONObject response) {
                if (response.optInt("success") == 1){
                    if (newsList == null)
                        newsList = new ArrayList<>();
                    newsList.clear();

                    JSONArray data = response.optJSONObject("result").optJSONArray("data");
                    for (int i = 0; i < data.length(); i++){
                        JSONObject jNews = data.optJSONObject(i);
                        News news = new News();
                        news.setName(jNews.optString("name"));
                        news.setImgURL(jNews.optString("imgURL"));
                        news.setIntro(jNews.optString("intro"));
                        news.setNewsURL(jNews.optString("newsURL"));
                        news.setCreateTime(jNews.optString("createTime"));

                        newsList.add(news);
                    }

                    newsAdapter.notifyDataSetChanged();
                } else {
                    Toast.makeText(MainActivity.this, response.optString("result"), Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onFailure() {
                Toast.makeText(MainActivity.this, "网络异常", Toast.LENGTH_LONG).show();
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Logger.e(requestCode + ", " + resultCode);
        switch (requestCode){
            case REQUEST_SCAN_CODE:
                IntentResult result = IntentIntegrator.parseActivityResult(resultCode, data);
                String lotId = result.getContents();
                if (!TextUtils.isEmpty(lotId)){
                    Logger.e("content: "+ lotId);
                    getParkingLotStatus(lotId);
                }
                break;
        }
    }

    private void getParkingLotStatus(final String lotId){
        try {
            JSONObject fparam = new JSONObject();
            fparam.put("uid", user.getReserveSysId())
                    .put("lotId", lotId);

            HttpRequest.post(URLConstant.HOST, "parkingData", fparam, new HttpRequest.HttpRequestCallback() {
                @Override
                public void onSuccess(JSONObject response) {
                    if (response.optInt("success") == 1){
                        JSONObject jPlStatus = response.optJSONObject("result");
                        final String msg = jPlStatus.optString("msg");
                        final String function = jPlStatus.optString("function");
                        final String startTime = jPlStatus.optString("startTime");
                        final String endTime = jPlStatus.optString("endTime");
                        final int code = jPlStatus.optInt("code");
                        switch (code){
                            case 0:
                                new AlertDialog.Builder(MainActivity.this)
                                        .setTitle("提示")
                                        .setMessage(msg)
                                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                dialog.dismiss();
                                                callFunction(function, lotId, startTime, endTime);
                                            }
                                        })
                                        .setNegativeButton("返回", new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                dialog.dismiss();
                                            }
                                        })
                                        .create().show();
                                break;
                            case 1:
                                new AlertDialog.Builder(MainActivity.this)
                                        .setTitle("提示")
                                        .setMessage(msg)
                                        .setNegativeButton("返回", new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                dialog.dismiss();
                                            }
                                        })
                                        .create().show();
                                break;
                        }

                    } else {
                        Toast.makeText(MainActivity.this, response.optString("result"), Toast.LENGTH_LONG).show();
                    }
                }

                @Override
                public void onFailure() {
                    Toast.makeText(MainActivity.this, "网络异常", Toast.LENGTH_LONG).show();
                }
            });
        } catch (JSONException e){
            e.printStackTrace();
        }
    }

    /**
     *
     * @param funcName allowed function's name
     * @param params lotId, startTime, endTime
     */
    private void callFunction(String funcName, Object... params){
        switch (funcName){
            case "reserveParkingLotById":
//                showPopUpWindow((String) params[0], (String) params[1]);
                Logger.e("不该被调用"); // TODO 待测
                break;
            case "updateAppStatus":
                updateAppStatus(user.getReserveSysId(), (String) params[0]);
                break;
            case "reportViolation":
                Intent intent = new Intent(MainActivity.this, ReportActivity.class);
                intent.putExtra("lotId", (String) params[0]);
                startActivity(intent);
                break;
            case "reserveLotAndParkingByParams":
                showPopUpWindow((String) params[0], (String) params[1]);
                break;
        }
    }

    private void showPopUpWindow(final String lotId, String excludeTimeFrom){
        if (timePicker == null){
            timePicker = new SimpleDateTimePicker(MainActivity.this);
            timePicker.setOnDateTimeSelectedListener(new SimpleDateTimePicker.OnDateTimeSelectedListener() {
                @Override
                public void onDateTimeSelected(int year, int month, int dayOfMonth, int hourOfDay, int minute) {
                    try {
                        String endTime = String.format("%d-%d-%d %02d:%02d", year, month + 1, dayOfMonth, hourOfDay, minute);
                        reserveLotAndParking(lotId, endTime);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        timePicker.setTimeType(SimpleDateTimePicker.TIME_TYPE.START_TIME);
        timePicker.setStartTime(new Date());
        timePicker.setTimeType(SimpleDateTimePicker.TIME_TYPE.END_TIME);
        timePicker.setTitle("选择结束时间");
        timePicker.setExcludeTimeFrom(DateTimeUtil.parse(excludeTimeFrom));
        timePicker.show();
    }

    private void reserveLotAndParking(String lotId, String endTime) throws JSONException {
        JSONObject fparam = new JSONObject();
        fparam.put("uid", user.getReserveSysId())
                .put("lotId", lotId)
                .put("endTime", endTime);

        HttpRequest.post(URLConstant.HOST, "reserveLotAndParkingByParams", fparam, new HttpRequest.HttpRequestCallback() {
            @Override
            public void onSuccess(JSONObject response) {
                if (response.optInt("success") == 1){
                    Toast.makeText(MainActivity.this, "预约成功并开始停车", Toast.LENGTH_LONG).show();
//                    TODO
                } else
                    Toast.makeText(MainActivity.this, response.optString("result"), Toast.LENGTH_LONG).show();
            }

            @Override
            public void onFailure() {
                Toast.makeText(MainActivity.this, "网络异常", Toast.LENGTH_LONG).show();
            }
        });
    }

    private void updateAppStatus(String uid, String lotId){
        try {
            JSONObject fparam = new JSONObject()
                    .put("uid", uid)
                    .put("lotId", lotId);

            HttpRequest.post(URLConstant.HOST, "updateAppStatus", fparam, new HttpRequest.HttpRequestCallback() {
                @Override
                public void onSuccess(JSONObject response) {
                    if (response.optInt("success") == 1){
                        Toast.makeText(MainActivity.this,
                                response.optJSONObject("result").optString("msg"), Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(MainActivity.this, response.optString("result"), Toast.LENGTH_LONG).show();
                    }
                }

                @Override
                public void onFailure() {
                    Toast.makeText(MainActivity.this, "网络异常", Toast.LENGTH_LONG).show();
                }
            });
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private static class NewsAdapter extends BaseAdapter {
        private List<News> newsList;
        private Context context;

        public NewsAdapter(Context context, List<News> newsList){
            this.context = context;
            this.newsList = newsList;
        }

        @Override
        public int getCount() {
            return newsList.size();
        }

        @Override
        public Object getItem(int position) {
            return newsList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            MainActivity.ViewHolder holder;
            if (convertView == null){
                convertView = LayoutInflater.from(context).inflate(R.layout.item_news, null);
                holder = new MainActivity.ViewHolder();
                holder.imageView = convertView.findViewById(R.id.img_photo);
                holder.name = convertView.findViewById(R.id.tv_name);
                holder.intro = convertView.findViewById(R.id.tv_intro);
                holder.time = convertView.findViewById(R.id.tv_time);

                convertView.setTag(holder);
            } else
                holder = (MainActivity.ViewHolder) convertView.getTag();
            // update holder
            News news = newsList.get(position);
            holder.name.setText(news.getName());
            holder.intro.setText(news.getIntro());
            holder.time.setText(news.getCreateTime());
            Glide.with(context)
                    .load(news.getImgURL())
                    .placeholder(R.mipmap.defalut)
                    .error(R.mipmap.defalut)
                    .into(holder.imageView);

            return convertView;
        }
    }

    private static class ViewHolder{
        ImageView imageView;
        TextView name, intro, time;
    }
}
